#!/usr/bin/env node

/**
 * 金牛座API表列表获取测试脚本
 * 
 * 此脚本用于测试从API获取数据库表列表的功能
 * @author Urban Lifeline Team
 */

import axios from 'axios';
import fs from 'fs';
import path from 'path';
import minimist from 'minimist';
import ora from 'ora';
import chalk from 'chalk';
import { fileURLToPath } from 'url';

// 获取当前文件目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 解析命令行参数
const args = minimist(process.argv.slice(2));
const LOG_API = args['log-api'] || false;
const SCHEMA = args.schema || null;

// 获取配置
let config;
try {
    const configPath = path.resolve(__dirname, './env.config.js');
    // 使用动态导入
    const configModule = await import(configPath);
    config = configModule.default;
} catch (error) {
    console.error(chalk.red('错误: 无法加载环境配置文件'), error.message);
    process.exit(1);
}

// 创建日志目录
const logDir = path.join(__dirname, 'logs');
if (LOG_API && !fs.existsSync(logDir)) {
    fs.mkdirSync(logDir);
}

// 记录API日志
function logApiRequest(method, url, data = null, response = null, error = null) {
    if (!LOG_API) return;

    const timestamp = new Date().toISOString();
    const logFile = path.join(logDir, `api_${new Date().toISOString().slice(0, 10)}.log`);

    let logEntry = `[${timestamp}] ${method} ${url}\n`;

    if (data) {
        logEntry += `请求数据: ${JSON.stringify(data, null, 2)}\n`;
    }

    if (response) {
        logEntry += `响应状态: ${response.status}\n`;
        logEntry += `响应数据: ${JSON.stringify(response.data, null, 2)}\n`;
    }

    if (error) {
        logEntry += `错误: ${error.message}\n`;
        if (error.response) {
            logEntry += `响应状态: ${error.response.status}\n`;
            logEntry += `响应数据: ${JSON.stringify(error.response.data, null, 2)}\n`;
        }
    }

    logEntry += '----------------------------------------\n\n';

    fs.appendFileSync(logFile, logEntry);
}

/**
 * 处理表列表响应
 * @param {Object|Array} response - API响应数据
 * @returns {Array} 处理后的表列表数组
 */
function processTableListResponse(response) {
    // 处理不同格式的响应
    if (Array.isArray(response)) {
        // 标准数组格式
        return response;
    } else if (response && response.tablelist && Array.isArray(response.tablelist)) {
        // 嵌套格式 {tablelist: [...]}
        return response.tablelist;
    } else if (response && response.data) {
        // 标准API响应格式 {data: ...}
        if (Array.isArray(response.data)) {
            return response.data;
        } else if (response.data.tablelist && Array.isArray(response.data.tablelist)) {
            return response.data.tablelist;
        }
    }

    // 无法识别的格式
    console.error(chalk.yellow('警告: 无法识别的表列表响应格式'));
    return [];
}

/**
 * 获取表列表
 */
async function getTableList() {
    const schema = SCHEMA || config.SCHEMA_NAME;
    if (!schema) {
        console.error(chalk.red('错误: 未指定Schema，请使用--schema参数指定'));
        process.exit(1);
    }

    const spinner = ora(`正在获取Schema [${chalk.yellow(schema)}] 的表列表...`).start();

    try {
        const baseURL = config.AUTO_API_BASE_URL;
        const apiUrl = `${baseURL}/findby?tbName=findbytableSchema`;

        // 从文件中读取token
        const tokenPath = path.resolve(__dirname, './token.json');
        let token;

        if (fs.existsSync(tokenPath)) {
            const tokenData = JSON.parse(fs.readFileSync(tokenPath, 'utf8'));
            token = tokenData.token;
        } else {
            spinner.fail(chalk.red('错误: 找不到令牌文件，请先执行登录或刷新令牌'));
            process.exit(1);
        }

        // 发起请求获取表列表
        const response = await axios({
            method: 'post',
            url: apiUrl,
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            data: {
                tablelist: {
                    tableSchema: schema
                }
            }
        });

        // 记录API请求日志
        logApiRequest('POST', apiUrl, { tablelist: { tableSchema: schema } }, response);

        // 处理响应
        if (response.data && response.data.success) {
            // 处理表列表响应
            const tableList = processTableListResponse(response.data.data);

            spinner.succeed(chalk.green(`成功获取表列表，共 ${tableList.length} 个表`));

            // 显示表列表
            if (tableList.length > 0) {
                console.log(chalk.blue('\n表列表:'));

                // 创建一个表格格式输出
                console.log('┌' + '─'.repeat(40) + '┬' + '─'.repeat(50) + '┐');
                console.log('│ ' + chalk.yellow('表名'.padEnd(38)) + ' │ ' + chalk.yellow('表注释'.padEnd(48)) + ' │');
                console.log('├' + '─'.repeat(40) + '┼' + '─'.repeat(50) + '┤');

                // 只显示前10个表
                const displayCount = Math.min(tableList.length, 10);
                for (let i = 0; i < displayCount; i++) {
                    const table = tableList[i];
                    console.log('│ ' + chalk.cyan(String(table.tableName || '').padEnd(38)) + ' │ ' +
                        String(table.tableComment || '').padEnd(48) + ' │');
                }

                console.log('├' + '─'.repeat(40) + '┼' + '─'.repeat(50) + '┤');
                if (tableList.length > 10) {
                    console.log('│ ' + `... 还有 ${tableList.length - 10} 个表未显示`.padEnd(89) + ' │');
                    console.log('└' + '─'.repeat(40) + '┴' + '─'.repeat(50) + '┘');
                } else {
                    console.log('└' + '─'.repeat(40) + '┴' + '─'.repeat(50) + '┘');
                }
            }

            return tableList;
        } else {
            spinner.fail(chalk.red(`获取表列表失败: ${response.data.message || '未知错误'}`));
            return [];
        }
    } catch (error) {
        logApiRequest('POST', `${config.AUTO_API_BASE_URL}/findby?tbName=findbytableSchema`,
            { tablelist: { tableSchema: schema } }, null, error);

        spinner.fail(chalk.red('获取表列表失败'));

        if (error.response) {
            console.error(`状态码: ${error.response.status}`);
            console.error(`错误信息: ${JSON.stringify(error.response.data, null, 2)}`);
        } else if (error.request) {
            console.error('无法连接到服务器，请检查网络连接或API地址是否正确');
        } else {
            console.error(`错误: ${error.message}`);
        }

        return [];
    }
}

/**
 * 显示测试数据响应处理能力
 */
function testResponseProcessing() {
    console.log(chalk.blue('\n===== 测试表列表响应处理功能 ====='));

    // 测试标准数组响应
    const standardResponse = [
        { tableName: 'test_table1', tableComment: '测试表1' },
        { tableName: 'test_table2', tableComment: '测试表2' }
    ];

    console.log(chalk.yellow('\n1. 标准数组响应:'));
    console.log(`输入: ${JSON.stringify(standardResponse, null, 2)}`);
    const standardResult = processTableListResponse(standardResponse);
    console.log(`输出: ${JSON.stringify(standardResult, null, 2)}`);

    // 测试嵌套响应
    const nestedResponse = {
        tablelist: [
            { tableName: 'nested_table1', tableComment: '嵌套测试表1' },
            { tableName: 'nested_table2', tableComment: '嵌套测试表2' }
        ]
    };

    console.log(chalk.yellow('\n2. 嵌套响应:'));
    console.log(`输入: ${JSON.stringify(nestedResponse, null, 2)}`);
    const nestedResult = processTableListResponse(nestedResponse);
    console.log(`输出: ${JSON.stringify(nestedResult, null, 2)}`);

    // 测试标准API响应
    const apiResponse = {
        data: [
            { tableName: 'api_table1', tableComment: 'API测试表1' },
            { tableName: 'api_table2', tableComment: 'API测试表2' }
        ]
    };

    console.log(chalk.yellow('\n3. 标准API响应:'));
    console.log(`输入: ${JSON.stringify(apiResponse, null, 2)}`);
    const apiResult = processTableListResponse(apiResponse);
    console.log(`输出: ${JSON.stringify(apiResult, null, 2)}`);
}

/**
 * 主函数
 */
async function main() {
    console.log(chalk.blue('===== 金牛座API表列表获取测试 ====='));

    // 显示配置信息
    console.log(chalk.blue('\n配置信息:'));
    console.log(`  API基础URL: ${chalk.yellow(config.AUTO_API_BASE_URL)}`);
    console.log(`  项目ID: ${chalk.yellow(config.PROJECT_ID || '未指定')}`);
    console.log(`  Schema: ${chalk.yellow(SCHEMA || config.SCHEMA_NAME || '未指定')}`);
    console.log(`  API日志: ${chalk.yellow(LOG_API ? '已启用' : '已禁用')}`);

    // 测试响应处理能力
    if (!SCHEMA) {
        testResponseProcessing();
        console.log(chalk.yellow('\n要获取实际的表列表，请使用 --schema 参数指定数据库schema'));
        return;
    }

    // 获取真实表列表
    await getTableList();
}

// 执行主函数
main()
    .then(() => {
        console.log(chalk.green('\n测试完成'));
        process.exit(0);
    })
    .catch(error => {
        console.error(chalk.red('\n执行测试时发生错误:'), error);
        process.exit(1);
    }); 